package com.example.auth.service.impl;

import com.example.auth.dto.ProjectDTO;
import com.example.auth.dto.ProjectEvaluationDTO;
import com.example.auth.entity.ProjectEvaluation;
import com.example.auth.entity.User;
import com.example.auth.repository.ProjectEvaluationRepository;
import com.example.auth.service.ProjectEvaluationService;
import com.example.auth.service.ProjectService;
import com.example.auth.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

/**
 * Project evaluation service implementation class
 */
@Service
public class ProjectEvaluationServiceImpl implements ProjectEvaluationService {

    private static final Logger logger = LoggerFactory.getLogger(ProjectEvaluationServiceImpl.class);

    @Autowired
    private ProjectEvaluationRepository projectEvaluationRepository;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private UserService userService;

    @Override
    @Transactional
    public ProjectEvaluationDTO createOrUpdateEvaluation(Long projectId, Integer score, String comment, Long evaluatedBy) {
        logger.info("Creating or updating project evaluation, Project ID: {}, Score: {}, Evaluated By ID: {}", projectId, score, evaluatedBy);

        // Find existing evaluation
        Optional<ProjectEvaluation> existingEvaluation = projectEvaluationRepository.findByProjectId(projectId);

        ProjectEvaluation evaluation;
        if (existingEvaluation.isPresent()) {
            // Update existing evaluation
            logger.info("Updating existing evaluation, Evaluation ID: {}", existingEvaluation.get().getId());
            evaluation = existingEvaluation.get();
            evaluation.setScore(score);
            evaluation.setComment(comment);
        } else {
            // Create new evaluation
            logger.info("Creating new evaluation");
            evaluation = new ProjectEvaluation();
            evaluation.setProjectId(projectId);
            evaluation.setScore(score);
            evaluation.setComment(comment);
            evaluation.setEvaluatedBy(evaluatedBy);
        }

        // Save evaluation
        evaluation = projectEvaluationRepository.save(evaluation);
        logger.info("Evaluation saved successfully, Evaluation ID: {}", evaluation.getId());

        // Update project status to completed
        if ("Waiting for Review".equals(projectService.getProjectById(projectId).getStatus())) {
            projectService.updateProjectStatus(projectId, "Completed");
            logger.info("Project status updated to Completed after evaluation, Project ID: {}", projectId);
        }

        // Get project and evaluator information for DTO creation
        ProjectDTO project = projectService.getProjectById(projectId);
        User evaluator = userService.findById(evaluatedBy);
        String evaluatorName = evaluator != null ? evaluator.getUsername() : "Unknown User";

        return ProjectEvaluationDTO.fromEntity(evaluation, project.getTitle(), evaluatorName);
    }

    @Override
    public ProjectEvaluationDTO getEvaluationByProjectId(Long projectId) {
        logger.info("Getting project evaluation, Project ID: {}", projectId);

        Optional<ProjectEvaluation> evaluation = projectEvaluationRepository.findByProjectId(projectId);

        if (evaluation.isEmpty()) {
            logger.info("Project evaluation does not exist, Project ID: {}", projectId);
            return null;
        }

        // Get project and evaluator information
        ProjectDTO project = projectService.getProjectById(projectId);
        User evaluator = userService.findById(evaluation.get().getEvaluatedBy());
        String evaluatorName = evaluator != null ? evaluator.getUsername() : "Unknown User";

        logger.info("Successfully retrieved project evaluation, Evaluation ID: {}", evaluation.get().getId());
        return ProjectEvaluationDTO.fromEntity(evaluation.get(), project.getTitle(), evaluatorName);
    }

    @Override
    @Transactional
    public boolean deleteEvaluation(Long projectId) {
        logger.info("Deleting project evaluation, Project ID: {}", projectId);

        Optional<ProjectEvaluation> evaluation = projectEvaluationRepository.findByProjectId(projectId);

        if (evaluation.isEmpty()) {
            logger.info("Project evaluation does not exist, cannot delete, Project ID: {}", projectId);
            return false;
        }

        // Check current project status before deleting evaluation
        ProjectDTO project = projectService.getProjectById(projectId);
        boolean shouldUpdateStatus = "Completed".equals(project.getStatus());

        projectEvaluationRepository.delete(evaluation.get());
        logger.info("Project evaluation deleted successfully, Evaluation ID: {}", evaluation.get().getId());

        // If project was completed, update status back to Waiting for Review
        if (shouldUpdateStatus) {
            // Update project status based on tasks to re-evaluate the correct status
            projectService.updateProjectStatusBasedOnTasks(projectId);
            logger.info("Project status re-evaluated after evaluation deletion, Project ID: {}", projectId);
        }

        return true;
    }
}